"""
魔法方法篇
"""


class Animal:
    __hp = 1

    def __Init__(self, HP):
        self.__hp = HP

    @staticmethod
    def drink():
        print("喝水")

    @staticmethod
    def eat():
        print("吃饭")

    def get_Hp(self):
        return self.__hp

    def change_Hp(self, HP):
        self.__hp = HP


class Dog(Animal):  # 在类后面的括号中去加入父类,多个父类时使用逗号连接
    __hp = 5

    def eat(self):
        super().eat()  # super在查找时会遵循MRO方法，可以通过mro方法查询
        print("吃骨头")


animal = Animal()
animal.change_Hp(20)
print(animal._Animal__hp)  # Python中的私有变量无法直接访问，如果要访问，要写类名并在类名前加_
dog = Dog()
dog.eat()
print(isinstance(dog, Animal))  # 判断是否属于类
print(issubclass(Dog, Animal))  # 判断是否为子类
print(Dog.__dict__)
print(Dog.mro())


# 当使用类的属性时，如果使用默认的字典存储，会浪费大量的空间
class Cat:
    __slots__ = ["age", "name"]  # 使用slots语句会使用列表存放属性，减小内存消耗，子类不会继承，仍然可以使用字典进行存储

    def __Init__(self, age, name):
        self.name = name
        self.age = age

    '''
    def __New__(cls(类))  # 创建新对象的时候会调用new方法
    def __del__()  # 销毁对象的时候会调用del方法，一个对象没有引用的时候才会被销毁
    '''
    # 如果想对某种运算进行重写u，也可以用到类


class CalStr(str):
    def __add__(self, other):
        return len(self) + len(other)
    # 例如将加法重写为计算两者长度和


'''
属性值族函数
hasattr(类，“属性”)可以判断是否含有这个属性 
getattr（类，”属性“）可以得到对应属性值 对应类内置方法是__getattribute__(), 可通过修改内置方法重写方法
当访问的属性不存在会触发__getattr__()方法
setattr（类， ”属性“， 属性值）为对应属性赋值  对应__setattr__()方法
delattr（类， ”属性“）删除特定属性  对应__delattr__()方法
'''

'''
索引，切片相关魔法方法
__index__()方法用于对象作为索引时
__getitem__()方法用于对象被索引时
__setitem()方法用于在修改值时
'''

"""
迭代相关魔法方法
__iter__(),定义了这个而没有定义下面一个代表是可迭代对象
__next__()，定义了这个代表是迭代器
python找不到上面两个方法时会调用__getitem__()方法
"""

"""
包含检测，对应in 和 not in
__contains__(self,item)
python找不到这个魔法方法时会去调用__iter__()和__next__()
"""

"""
bool()函数对应的魔法方法是__bool__()
当其未定义会由__len__()代偿
"""

"""
< __lt__()
<= __le__()
> __gt__()
>= __ge__()
== __eq__()
!= __ne__()
"""

"""
__call__(), 调用对象时调用
"""

"""
eval()函数，去引号后执行，例如eval("1+2"),结果为3
字符串函数__str__() __repr__()repr可以对str代偿
"""

"""
property(get, set, del)
给属性赋值对应方法后，即可实现对其修改
@property可以实现只读操作
原理是x=property(x),此处x默认在get即读函数位置，所以可以实现只读操作
"""
